package gui.cen.table;

import core.utils.EPara;
import core.utils.Utils;
import gui.Segl2;
import gui.utils.Borders;
import javax.swing.JPanel;
import gui.utils.Para;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/*Author: John Archer, Contact: john.archer.jpa@gmail.com*/
public class TablePane extends JPanel{
    private DecimalFormat df;
    private Segl2 SegL2;
    private String [] colN;
    private int [] colW;
    private int tableWidth;
    
    public TablePane(Segl2 SegL2){
        this.SegL2 = SegL2;
        this.setBackground(new Color(102, 102, 102));
        this.df = new DecimalFormat("#0.0000");
        this.setOpaque(true);
        this.repaint();
    }


    public void paintComponent(Graphics g) {dTable(g);}

    public void updateTable(){this.repaint();}

    private Graphics2D bg = null;
    private Image offScreen = null;

    private String getSpace(int s){
        String space = "";
        for(int x=0; x<s; x++){
            space = space + " ";
        }
        return space;
    }

    private void dTable(Graphics g){
        try{
            if(Para.POSTS==null){
                colN = new String[10];colW = new int[10];
                colN[0]="Site";colW[0]=colN[0].length()+5;
                colN[1]="Cover";colW[1]=colN[1].length()+4;
                colN[2]="Adenine";colW[2]=colN[2].length()+2;
                colN[3]="Thymine";colW[3]=colN[3].length()+2;
                colN[4]="Guanine";colW[4]=colN[4].length()+2;
                colN[5]="Cytosine";colW[5]=colN[5].length()+2;
                colN[6]="Deletion";colW[6]=colN[6].length()+2;
                colN[7]="Con.";colW[7]=colN[7].length()+2;
                colN[8]="HPS";colW[8]=colN[8].length()+2;
                colN[9]="Codons (No. of sites with consensus '*': "+Para.STOPS+")";colW[9]=colN[9].length()+30;
                tableWidth = (colW[0] + colW[1] + colW[2] + colW[3] + colW[4] + colW[5] + colW[6] + colW[7] + colW[8] + colW[9]) * Borders.SEQ_CHAR_WIDTH;
            }
            else{
                colN = new String[14];colW = new int[14];
                colN[0]="Site";colW[0]=colN[0].length()+5;
                colN[1]="Cover";colW[1]=colN[1].length()+4;
                colN[2]="Adenine";colW[2]=colN[2].length()+2;
                colN[3]="Thymine";colW[3]=colN[3].length()+2;
                colN[4]="Guanine";colW[4]=colN[4].length()+2;
                colN[5]="Cytosine";colW[5]=colN[5].length()+2;
                colN[6]="Deletion";colW[6]=colN[6].length()+2;
                colN[7]="P(A)";colW[7]=colN[7].length()+5;
                colN[8]="P(T)";colW[8]=colN[8].length()+5;
                colN[9]="P(G)";colW[9]=colN[9].length()+5;
                colN[10]="P(C)";colW[10]=colN[10].length()+5;
                colN[11]="Con.";colW[11]=colN[11].length()+2;
                colN[12]="HPS";colW[12]=colN[12].length()+2;
                colN[13]="Codons (No. of sites with consensus '*': "+Para.STOPS+")";colW[13]=colN[13].length()+20;
                tableWidth = (colW[0] + colW[1] + colW[2] + colW[3] + colW[4] + colW[5] + colW[6] + colW[7] + colW[8] + colW[9] + colW[10] + colW[11] + colW[12] + colW[13] ) * Borders.SEQ_CHAR_WIDTH;
            }

            final int imageHeight = SegL2.getHeight();
            final int imageWidth = tableWidth;
            this.setLayout(new FlowLayout(){public Dimension preferredLayoutSize(Container cont) {return (new Dimension(imageWidth, imageHeight));}});
            offScreen = this.createImage(imageWidth, imageHeight);
            bg = (Graphics2D)offScreen.getGraphics();
            bg.setColor(new Color(102, 102, 102));
            bg.fillRect(0, 0, imageWidth, imageHeight);

            int yLocation = 20;
            int _ = 1;

            bg.setColor(new Color(178, 178, 178));
            bg.setFont(Borders.getFont(Borders.SEQFONTBLD));
            for(int i=0; i<colN.length; i++){
                int space = colW[i] - colN[i].length();
                 bg.drawString(colN[i] + getSpace(space), (_ * Borders.SEQ_CHAR_WIDTH), yLocation);
                 _ += colW[i];
            }
            bg.setFont(Borders.getFont(Borders.SEQFONT));
            //must be dividible by 2
            int padding = (int)Borders.SEQCHARHEIGHT/4;
            int yIncrement = Borders.SEQCHARHEIGHT + padding;
            Para.NO_OF_ROWS = (int)(this.getHeight() / yIncrement);
            int templateEndSite = Para.TPOS + Para.NO_OF_ROWS;
            double  a_a, t_t, g_g, c_c, d_d, pA, pT, pG, pC;
            int hps, cover;
            String codons = "";

            yLocation = yLocation + 10;
            for (int s = Para.TPOS; s < templateEndSite && s<Para.NUCS[0].length; s++){
                yLocation = yLocation + yIncrement;
                cover = Para.NUCS[0][s] +Para.NUCS[1][s] +Para.NUCS[2][s] + Para.NUCS[3][s] + Para.NUCS[4][s];
                a_a = (double)Para.NUCS[0][s]/(double)cover;
                t_t = (double)Para.NUCS[1][s]/(double)cover;
                g_g = (double)Para.NUCS[2][s]/(double)cover;
                c_c = (double)Para.NUCS[3][s]/(double)cover;
                d_d = (double)Para.NUCS[4][s]/(double)cover;
                if(Para.POSTS!=null){
                    pA = Para.POSTS[0][s];
                    pT = Para.POSTS[1][s];
                    pG = Para.POSTS[2][s];
                    pC = Para.POSTS[3][s];
                }
                else{pA=pT=pG=pC=0;}
                if((s - Para.FRAME)%3==0 && s<(Para.CON.length - 3)){
                    HashMap <String, Integer> siteCodons = Para.CODONS[s];
                    Iterator iter = siteCodons.entrySet().iterator();
                    while (iter.hasNext()) {
                        Map.Entry pairs = (Map.Entry)iter.next();
                        String key = (String)pairs.getKey();
                        int value = ((Integer)pairs.getValue()).intValue();
                        codons += key+":"+Utils.trans(key)+" ("+value+"), ";
                    }
                    codons += " ["+ (codons.split(",").length - 1) +"]";
                }
                else{codons="";}

                if(Para.POSTS==null){if(codons.length() > colW[9]){codons = codons.substring(0, colW[9] - 24) + "..... (see saved table)"; }}
                else{if(codons.length() > colW[13]){codons = codons.substring(0, colW[13] - 24) + "..... (see saved table)"; }}
                hps = Para.HPS_CATS[s];
                String [] columnValues = new String[colN.length];
                columnValues[0] = s + "";
                columnValues[1] = cover + "";
                columnValues[2] = df.format(a_a)+"";
                columnValues[3] = df.format(t_t)+"";
                columnValues[4] = df.format(g_g)+"";
                columnValues[5] = df.format(c_c)+"";
                columnValues[6] = df.format(d_d)+"";
                if(Para.POSTS!=null){
                    columnValues[7] = df.format(pA)+"";
                    columnValues[8] = df.format(pT)+"";
                    columnValues[9] = df.format(pG)+"";
                    columnValues[10] = df.format(pC)+"";
                    columnValues[11] = Para.CON[s]+"";
                    columnValues[12] = hps+"";
                    columnValues[13] = codons;
                }
                else{
                    columnValues[7] = Para.CON[s]+"";
                    columnValues[8] = hps+"";
                    columnValues[9] = codons;
                }
                _ = 1;
                double [] vals = {a_a, t_t, g_g, c_c};
                //if(Index_row==Para.TABLE_ROW){comp.setBackground(Color.YELLOW);}
                if(Utils.getSecondHighestValue(vals) >= ((double)EPara.MIN_FREQ_HIGHLIGHT/100.00) && hps<=EPara.HPS_LENGTH){
                    bg.setColor(new Color(75, 75, 75));
                    bg.fill(new Rectangle(5, yLocation - yIncrement + padding + (padding/2), tableWidth, Borders.SEQCHARHEIGHT + (padding/2)));
                    bg.setColor(new Color(178, 178, 178));
                }
                for(int i=0; i<colN.length; i++){
                    int space = colW[i] - colN[i].length();
                    if(i==0){
                        bg.setFont(Borders.getFont(Borders.SEQFONTBLD));
                        bg.drawString(columnValues[i] + getSpace(space), (_ * Borders.SEQ_CHAR_WIDTH), yLocation);
                        _ += colW[i];
                        bg.setFont(Borders.getFont(Borders.SEQFONT));
                    }
                    else{
                        bg.drawString(columnValues[i] + getSpace(space), (_ * Borders.SEQ_CHAR_WIDTH), yLocation);
                        _ += colW[i];
                    }
                }
            }
            g.drawImage(offScreen, 0, 0, imageWidth, imageHeight, this);
        }
        catch(Exception e){}
    }
}